package no.sachmuld.methodcombination.examples.reflection.combo.courier;

import no.sachmuld.methodcombination.api.*;
import no.sachmuld.methodcombination.api.reflection.component.ContractCheckingMethodCombination;
import no.sachmuld.methodcombination.examples.reflection.combo.StandardCrosscutting;

/**
 *
 */
public class Courier {

    private BehaviourChain<CrosscuttingBehaviour> chain = new BehaviourChain<>();

    public Courier() {

        with(new CourierBehaviour() {

            @Override
            public Condition beforeDeliver(Package pkg, Context context) {
                return new Condition("package weight < 3", pkg.getWeightInKg() < 3);
            }

            @Override
            public Delivery deliver(Package pkg, MethodInvocation<Delivery> methodInvocation) {
                System.out.println("Courier.deliver");
                return new Delivery(6);
            }

            @Override
            public Condition afterDeliver(Package pkg, Delivery delivery, Context context) {
                return new Condition("delivery time < 8", delivery.getDeliveryTimeInHours() < 8);
            }

        });
    }

    public final Delivery deliver(final Package pkg) {
        return new ContractCheckingMethodCombination<>(new StandardCrosscutting<CrosscuttingBehaviour, Delivery>()).build(CourierBehaviour.class, Courier.class, "deliver", Package.class).execute(this, chain, pkg);
    }

    final protected Courier with(CrosscuttingBehaviour... behaviours) {
        chain.addAll(behaviours);
        return this;
    }

}
